<template>
    <div class="page" v-loading="loading">
        <div class="flex-row flex-item">
            <tz-filter :show-net="false" @change="filterChange" :filter-data="filterData">
                <template v-slot:default="scope">
                    <el-select size="small" class="table-filter-item" v-model="scope.data.roleId" clearable placeholder="用户角色">
                        <el-option
                                v-for="item in roleList"
                                :key="item.roleId"
                                :label="item.roleName"
                                :value="item.roleId">
                        </el-option>
                    </el-select>
                    <el-input :maxlength="20" size="small" class="table-filter-item" v-model.trim="scope.data.realName" clearable placeholder="用户姓名"></el-input>
                </template>
            </tz-filter>
            <div class="flex1"></div>
            <el-button style="margin-left: 10px;"
                       v-if="$auth['setting_user_addUser']"
                       type="primary"
                       @click="addUser"
                       size="small">新增用户</el-button>
        </div>
        <tz-table
                ref="tzTable"
                highlight-current-row
                size="mini"
                :data="loadData">
            <el-table-column
                    prop="realName"
                    show-overflow-tooltip
                    label="用户名">
                <template slot-scope="scope">
                    <high-light :value="scope.row.realName" :keyword="filterData.realName"></high-light>
                </template>
            </el-table-column>
            <el-table-column
                    prop="username"
                    show-overflow-tooltip
                    label="登录账号">
            </el-table-column>
            <el-table-column
                    prop="groupName"
                    show-overflow-tooltip
                    label="分组"
                    :formatter="(row) => {
                       return row.groupName.map(item => item.groupName).join('，')
                     }">
            </el-table-column>
            <el-table-column
                    prop="roleEntityList"
                    label="授权角色">
                <template slot-scope="scope">
                    <el-tag
                            v-for="item in scope.row.roleEntityList"
                            :key="item.roleId"
                            size="mini"
                    >{{item.roleName}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="status" label="用户状态">
                <template slot-scope="scope">
                    <el-tag
                            size="mini"
                            :type="scope.row.status ? '' : 'success'"
                    >{{scope.row.status ? '启用' : '禁用'}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column
                    prop="lastLoginTime"
                    show-overflow-tooltip
                    label="最近一次登录时间"
                    :formatter="(row) => {
                       return row.lastLoginTime ? moment(row.lastLoginTime).format('YYYY-MM-DD HH:mm:ss') : '-'
                     }">
            </el-table-column>
            <el-table-column
                    prop="tag"
                    label="操作">
                <template slot-scope="scope">
                    <el-button v-if="$auth['setting_user_reset']" size="small" type="text" @click="resetPass(scope.row)">重置密码</el-button>
                    <el-button v-if="$auth['setting_user_update']" @click="editUser(scope.row)" size="small" type="text">编辑</el-button>
                    <el-button v-if="$auth['setting_user_delete']" @click="deleteUser(scope.row)" size="small" type="text">删除</el-button>
                    <el-button v-if="scope.row.status === 1 && $auth['setting_user_status']" @click="editStatus(scope.row)" size="small" type="text">停用</el-button>
                    <el-button v-else-if="$auth['setting_user_status']" @click="editStatus(scope.row)" size="small" type="text">启用</el-button>
                </template>
            </el-table-column>
        </tz-table>
        <el-drawer
                :title="drawerTitle"
                :visible.sync="drawer"
                direction="rtl">
            <div class="drawer-content" v-loading="dialogLoading">
                <el-form :model="userInfo" ref="userForm" :rules="rules" label-width="80px">
                    <el-form-item label="用户名" prop="realName">
                        <el-input :maxlength="20" show-word-limit v-model="userInfo.realName"></el-input>
                    </el-form-item>
                    <el-form-item label="登录账号" prop="username">
                        <el-input :maxlength="20" show-word-limit v-model="userInfo.username"></el-input>
                    </el-form-item>
                    <el-form-item label="用户组" prop="groupIds">
                        <el-checkbox-group v-model="userInfo.groupIds">
                            <el-checkbox v-for="item in allGroupsList"
                                         :disabled="!userGroupIds.includes(item.groupId)"
                                         :key="item.groupId"
                                         :label="item.groupId">{{item.groupName}}</el-checkbox>
                        </el-checkbox-group>
                    </el-form-item>

                    <el-form-item label="用户授权" prop="roleIdList">
                        <el-checkbox-group v-model="userInfo.roleIdList">
                            <el-checkbox v-for="item in roleList"
                                         :key="item.roleId"
                                         :disabled="roleStatus(item)"
                                         :label="item.roleId">{{item.roleName}}</el-checkbox>
                        </el-checkbox-group>
                    </el-form-item>
                    <el-form-item>
                        <div class="flex-item flex-row">
                            <div class="flex1"></div>
                            <el-button size="small" @click="drawer = false">取消</el-button>
                            <el-button size="small" type="primary" @click="saveOrUpdateRole">保存</el-button>
                        </div>
                    </el-form-item>
                </el-form>
            </div>
        </el-drawer>
    </div>
</template>

<script>
import tzTable from '@/components/tz-table'
import { mapState, mapActions } from 'vuex'
import moment from 'moment'
export default {
  name: 'userList',
  components: {
    tzTable
  },
  data() {
    return {
      moment,
      filterData: {
        roleId: '',
        realName: '',
      },
      loading: false,
      drawer: false,
      dialogLoading: false,
      drawerTitle: '',
      userInfo: {
        realName: '',
        username: '',
        groupIds: [],
        roleIdList: [],
        // 1超管。2普通用户
        userType: 2,
        userId: ''
      },
      rules: {
        realName: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        username: [
          { required: true, message: '请输入登录账号', trigger: 'blur' },
          { validator: (rule, value, callback) => {
            const regex = /^[a-zA-Z][a-zA-Z0-9_]*$/;
            if (regex.test(value)) {
              callback();
            } else {
              return callback(new Error('账户必须以字母开始且只能包含字母数字和下划线'));
            }
          }, trigger: 'blur' }
        ],
        groupIds: [
          { required: true, message: '请选择用户组', trigger: 'change' }
        ],
        roleIdList: [
          { required: true, message: '请选择用户角色', trigger: 'change' }
        ]
      },
      myRoleListIds: [],
      roleList: [],
      allGroupsList: [],
      isEq: 0
    }
  },
  mounted() {
    this.getMyRoles()
    this.getGroups()
  },
  methods: {
    ...mapActions('userInfo', ['updateUserInfo']),
    filterChange(res) {
      this.isEq = res.isEq
      this.refresh()
    },
    roleStatus(role) {
      return !(role.status && this.baseInfo.roleIdList.includes(role.roleId))
    },
    addUser() {
      this.editUser({
        realName: '',
        roleIdList: [],
        username: ''
      })
    },
    editStatus({userId, status}) {
      this.loading = true
      this.$http.get('/sys/user/updateUserStatus', {
        params: {
          status: status === 0 ? 1 : 0,
          userId
        }
      }).then(res => {
        this.$TZmessage.success('操作成功')
      }).catch(err => {
        this.$TZmessage.error(err.msg || '操作失败')
      }).finally(() => {
        this.loading = false
        this.refresh()
      })
    },
    editUser(row) {
      this.userInfo = {
        ...row,
        groupIds: row.groupName ? row.groupName.map(item => item.groupId) : [],
        roleIdList: (row.roleEntityList || []).map(item => item.roleId)
      }
      this.drawerTitle = row.userId ? '编辑用户' : '新增用户'
      this.drawer = true
      this.getMyRoles()
    },
    saveOrUpdateRole() {
      this.$refs.userForm.validate((valid) => {
        if (valid) {
          const { realName, roleIdList, groupIds, username, userId } = this.userInfo
          this.dialogLoading = true
          const params = {
            realName,
            roleIdList,
            username,
            groupId: groupIds.join(','),
            userType: 2
          }
          if (userId) {
            params.userId = userId
          }
          this.$http.post(userId ? '/sys/user/updateUserInfo' : '/sys/user/addUser', params).then(res => {
            this.$TZmessage.success(userId ? '保存成功' : '新增成功')
            this.drawer = false
            this.updateUserInfo()
            this.refresh()
          }).catch(err => {
            this.$TZmessage.error(err.msg || userId ? '保存失败' : '新增失败')
          }).finally(() => {
            this.dialogLoading = false
          })
        } else {
          return false;
        }
      });
    },
    refresh() {
      this.$refs.tzTable.refresh(true)
    },
    deleteUser(user) {
      this.$confirm(`是否删除用户${user.realName}`, '提示', {
        type: 'warning'
      }).then(() => {
        this.$http.delete(`/sys/user/deleteUser?userId=${user.userId}`).then(res => {
          this.$TZmessage.success('删除成功')
        }).catch(err => {
          this.$TZmessage.error(err.msg || '删除失败')
        }).finally(() => {
          this.refresh()
        })
      }).catch(err => {
        console.log('取消执行')
      })
    },
    resetPass(row) {
      this.$confirm('该用户密码重置为123456，原密码将失效，是否继续？', '提示', {
        confirmButtonText: '重置密码',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(res => {
        this.loading = true
        this.$http.post('/sys/user/reset/password', {
          userId: row.userId
        }).then(res => {
          this.$TZmessage.success('重置密码成功')
        }).catch(err => {
          this.$TZmessage.error(err.msg || '重置密码失败')
        }).finally(() => {
          this.loading = false
          this.refresh()
        })
      }).catch(err => {
        console.log('取消执行')
      })
    },
    getMyRoles() {
      this.dialogLoading = true
      const params = {
        pageNum: 1,
        pageSize: 999,
        userId: this.baseInfo.userId
      }
      this.$http.get('/sys/role/list', { params }).then(res => {
        this.myRoleListIds = (res.records || []).map(item => item.roleId)
        this.roleList = res.records
      }).catch(err => {
        this.$TZmessage.error(err.msg || '获取角色列表失败')
      }).finally(() => {
        this.dialogLoading = false
      })
    },
    loadData(page) {
      const { roleId, realName } = this.filterData
      const params = {...page, roleId, realName, isEq: this.isEq}
      return this.$http.get('/sys/user/list', { params }).then(res => {
        return {
          data: res.records || [],
          total: res.total
        }
      }).catch(err => {
        this.$TZmessage.error(err.msg || '获取列表失败')
      })
    },
    getGroups() {
      this.$http.get('/sys/user/getGroupList').then(res => {
        this.allGroupsList = res || []
      }).catch(err => {
        this.$TZmessage.error(err.msg || '获取用户组失败')
      })
    },
  },
  computed: {
    ...mapState('userInfo', ['baseInfo']),
    userGroupIds() {
      return this.baseInfo.groupId?.split(',') || []
    },
  }
}
</script>

<style lang="scss" scoped>
    .drawer-content {
        padding: 20px;
    }
</style>